home *** CD-ROM | disk | FTP | other *** search
- /* ——————————————————————————————————————————————————————————————————
- Filename: Bullet Field Mgr.c
- Dialog field bulleter, written for THINK C 4.0.5
- By Chris Johnson (chrisj@emx.utexas.edu)
- Version of: Thursday, August 8, 1991 2:46 PM
- Modified: Sunday, January 26, 1992 by Dale Talcott
- Handle international character sets
- Use round bullet instead of drawing a variable width rectangle
- Don't blame Mr. Johnson for bugs I introduced.
-
- Distribute freely, but say something nice about the author when
- you use it. Please send me a copy of any improvements you make
- so they can be incorporated into future versions.
-
- See the included file, "Bullet Field Mgr.h" for documentation.
- —————————————————————————————————————————————————————————————————— */
-
-
- #include "Bullet Field Mgr.h"
- #include <GestaltEqu.h>
- #include <Script.h>
-
-
- typedef struct {
- CQDProcs Procs;
- CQDProcs OProcs;
- Boolean SMEnabled;
- Boolean InUs;
- int Count;
- Rect BBox[];
- } BulletFieldRec, *BulletFieldPtr;
-
-
- pascal void BulletStdText(short ByteCount, Ptr TextBuf, Point Number, Point Denom);
- pascal short BulletStdTxMeas(short ByteCount, Ptr TextBuf,
- Point *Number, Point *Denom, FontInfo *info);
- int IsBulletField(GrafPtr CurPort, BulletFieldPtr Bull, Boolean);
-
- typedef pascal void (*stdtextp)(short, Ptr, Point, Point);
- typedef pascal short (*stdmeasp)(short, Ptr, Point *, Point *, FontInfo *);
-
- int BulletFieldCreate(
- DialogPtr Dialog,
- int NumItems,
- int FieldCount,
- int Field1, ...)
- {
- int Continue;
- GrafPtr OrigPort;
- BulletFieldPtr Bull;
- long lp;
-
- Continue = FALSE;
-
- GetPort(&OrigPort);
- SetPort(Dialog);
-
- Bull = (BulletFieldPtr) NewPtr(sizeof(BulletFieldRec) + ((long) sizeof(Rect) * FieldCount));
- if (Bull != NULL) {
- int *FieldItem;
- Rect *DestBBox;
-
- /* Determine if Script Manager present */
- lp = 0;
- if (Gestalt(gestaltScriptCount, &lp) == 0 && lp > 0)
- Bull->SMEnabled = true;
- else
- Bull->SMEnabled = false;
- Bull->InUs = false;
-
- /* Build the field boundary list. */
-
- Bull->Count = FieldCount;
-
- FieldItem = &Field1;
- DestBBox = Bull->BBox;
-
- while (--FieldCount >= 0) {
- short Type;
- Handle Hand;
-
- GetDItem(Dialog, NumItems + *FieldItem++, &Type, &Hand, DestBBox++);
- }
-
- /* Install the QuickDraw bottleneck procedures. */
-
- if ((((CGrafPtr) Dialog)->portVersion & 0xC000) != 0)
- SetStdCProcs(&Bull->Procs);
- else
- SetStdProcs((QDProcsPtr) &Bull->Procs);
- Bull->OProcs = Bull->Procs;
- Bull->Procs.textProc = (Ptr) BulletStdText;
- Bull->Procs.txMeasProc = (Ptr) BulletStdTxMeas;
- Dialog->grafProcs = (QDProcsPtr) &Bull->Procs;
-
- /* Indicate successful installation. */
-
- Continue = TRUE;
- }
-
- ((WindowPeek) Dialog)->refCon = (long) Bull;
-
- SetPort(OrigPort);
-
- return (Continue);
- }
-
-
- void BulletFieldDispose(Dialog)
- DialogPtr Dialog;
- {
- if (((WindowPeek) Dialog)->refCon != 0)
- DisposPtr((Ptr) ((WindowPeek) Dialog)->refCon);
-
- Dialog->grafProcs = NULL;
- }
-
-
- static pascal void
- BulletStdText(ByteCount, TextBuf, Numer, Denom)
- short ByteCount;
- Ptr TextBuf;
- Point Numer;
- Point Denom;
- {
- GrafPtr CurPort;
- BulletFieldPtr Bull;
-
- GetPort(&CurPort);
- Bull = (BulletFieldPtr) ((WindowPeek) CurPort)->refCon;
-
- if (IsBulletField(CurPort, Bull, true))
- {
- int i, j;
- short ct;
- int Width;
- FontInfo FntInfo;
-
- if (Bull->SMEnabled)
- {
- for (i = j = 0; i < ByteCount; i++)
- {
- ct = CharByte(TextBuf, i);
- if (ct == smSingleByte || ct == smFirstByte)
- j++;
- }
- }
- else
- j = ByteCount;
-
- if (j)
- {
- Bull->InUs = true;
- GetFontInfo(&FntInfo);
- Bull->InUs = false;
- Width = FntInfo.ascent;
- if (Width <= 0)
- Width = 2;
- else if (Width > 14)
- Width = 14;
- else
- Width = Width & ~1;
- }
-
- for (i = 0; i < j; i++)
- {
- Rect CharBox;
-
- CharBox.left = CurPort->pnLoc.h;
- CharBox.top = CurPort->pnLoc.v - Width + 1;
- CharBox.right = CharBox.left + Width;
- CharBox.bottom = CharBox.top + Width;
-
- InsetRect(&CharBox, 1, 1);
- FrameOval(&CharBox);
- PaintOval(&CharBox);
-
- Move(Width, 0);
- }
- }
- else
- {
- if (Bull)
- ((stdtextp)(Bull->OProcs.textProc))(ByteCount, TextBuf, Numer, Denom);
- else
- StdText(ByteCount, TextBuf, Numer, Denom);
- }
- }
-
- static pascal short
- BulletStdTxMeas (short ByteCount, Ptr TextBuf,
- Point *Numer, Point *Denom, FontInfo *info)
- {
- GrafPtr CurPort;
- BulletFieldPtr Bull;
-
- GetPort(&CurPort);
- Bull = (BulletFieldPtr) ((WindowPeek) CurPort)->refCon;
- /*
- * Use the system text measure unless in bullet field and
- * not measuring text drawing bullet
- */
- if (IsBulletField(CurPort, Bull, false) && Bull && !Bull->InUs)
- {
- int i, j;
- int ct;
- int Width;
- FontInfo FntInfo;
-
- if (Bull->SMEnabled)
- {
- for (i = j = 0; i < ByteCount; i++)
- {
- ct = CharByte(TextBuf, i);
- if (ct == smSingleByte || ct == smFirstByte)
- j++;
- }
- }
- else
- j = ByteCount;
- Bull->InUs = true;
- GetFontInfo (&FntInfo);
- Bull->InUs = false;
- Width = FntInfo.ascent;
- if (Width <= 0)
- Width = 2;
- else if (Width > 14)
- Width = 14;
- else
- Width = Width & ~1;
- return Width * j;
- }
- if (Bull)
- return ((stdmeasp)(Bull->OProcs.txMeasProc))(ByteCount, TextBuf, Numer, Denom, info);
- else
- return StdTxMeas (ByteCount, TextBuf, Numer, Denom, info);
- }
-
- static int IsBulletField(GrafPtr CurPort, BulletFieldPtr Bull, Boolean checkpen)
- {
- register int BulletField;
-
- BulletField = FALSE;
-
- if (Bull != NULL) {
- register int FieldCount;
- register Rect *Field;
- register Rect *Clip;
-
- FieldCount = Bull->Count;
- Field = Bull->BBox;
- Clip = &(*CurPort->clipRgn)->rgnBBox;
-
- while (--FieldCount >= 0)
- {
-
- /* The field should be bulleted if it is currently within the
- clipRgn of the dialog. */
-
- if (Clip->left >= Field->left && Clip->right <= Field->right) {
-
- if (Clip->top >= Field->top && Clip->bottom <= Field->bottom) {
-
- BulletField = TRUE;
- break;
- }
- }
-
- /* The field should also be bulleted if the pen is currently
- located inside it. */
-
- if (checkpen)
- {
- if (CurPort->pnLoc.h >= Field->left && CurPort->pnLoc.h <= Field->right
- && CurPort->pnLoc.v >= Field->top && CurPort->pnLoc.v <= Field->bottom)
- {
- BulletField = TRUE;
- break;
- }
- }
- Field++;
- }
- }
-
- return (BulletField);
- }
-
-
-